﻿using Activity.Comm;
using Activity.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Configuration;

namespace Activity.API
{
    /// <summary>
    /// 2018.5.1及夏季积分抽奖
    /// </summary>
    public class Lottery2018Handler
    {
        /// <summary>
        /// 领取开始时间5.1活动
        /// </summary>
        static readonly DateTime beginDate51 = new DateTime(2018, 4, 27, 0, 0, 0);
        /// <summary>
        /// 领取结束时间5.1活动
        /// </summary>
        static readonly DateTime endDate51 = new DateTime(2018, 5, 1, 23, 59, 59);
        
        /// <summary>
        /// 领取开始时间夏季活动
        /// </summary>
        static readonly DateTime beginDateSummer = new DateTime(2018, 5, 2, 0, 0, 0);
        /// <summary>
        /// 领取结束时间夏季活动
        /// </summary>
        static readonly DateTime endDateSummer = new DateTime(2018, 7, 31, 23, 59, 59);

        /// <summary>
        /// 使用的Redis数据库索引
        /// </summary>
        public const int RedisDatabaseIndex = 4;
        /// <summary>
        /// 测试
        /// </summary>
        static readonly string isDebug = WebConfigurationManager.AppSettings["isDebug"];

        private static object obj = new object();

        /// <summary>
        /// 抽奖
        /// </summary>
        /// <param name="type">类型:1－51劳动节抽奖(4.27-5.1);2－夏季抽奖(5.2-7.31)</param>
        /// <param name="openId"></param>
        /// <returns></returns>
        public Messages Lottery(int type, string openId)
        {
            if (string.IsNullOrWhiteSpace(openId))
                return new Messages() {IsSuc = false, Code = -1, Message = "无效的OPENID"};
            if (type != 1 || type != 2) new Messages() {IsSuc = false, Code = -1, Message = "无效类型"};
            if (type == 1)
            {
                if (DateTime.Now < beginDate51 && isDebug.ToLower() == "false")
                {
                    return new Messages {IsSuc = false, Code = -1, Message = "亲，活动还没开始呢"};
                }

                if (DateTime.Now > endDate51 && isDebug.ToLower() == "false")
                {
                    return new Messages {IsSuc = false, Code = -1, Message = "亲，活动已经结束了"};
                }
            }

            if (type == 2)
            {
                if (DateTime.Now < beginDateSummer && isDebug.ToLower() == "false")
                {
                    return new Messages {IsSuc = false, Code = -1, Message = "亲，活动还没开始呢"};
                }

                if (DateTime.Now > endDateSummer && isDebug.ToLower() == "false")
                {
                    return new Messages {IsSuc = false, Code = -1, Message = "亲，活动已经结束了"};
                }
            }

            var user = GetUser(openId);
            if(user.TotalIntegral<100) return new Messages { IsSuc = false, Code = -1, Message = "积分不足" };

            var map = LoggeryInfo(type);
            var list = new List<double>(map.Values);
            //var gifts = new List<string>(map.Keys);
            var method = new AliasMethod(list);
            var index = method.Next();
            //检查ipad,iphone,果汁机数量
            if (index == 3 || index == 4)
            {
                if (CheckLotteryCount(type, index))
                {
                    //TODO:重新抽奖
                    index = method.Next();
                }
            }
            lock (obj)
            {
                var dc = new ActivityEntities();
                var cardCode = string.Empty;
                if (index !=0)
                {
                    //奖品是优惠券才生成券码
                    cardCode = SaveErpLog(openId, type, index);
                }
                var log = new t_Lottery2018Activity_log()
                {
                    OpenID = openId,
                    ActivityType = type,
                    LotteryType = index,
                    LotteryTime = DateTime.Now,
                    CardCode = cardCode
                };
                dc.t_Lottery2018Activity_log.Add(log);
                try
                {
                    dc.SaveChanges();
                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                    return new Messages { IsSuc = false, Code = -1, Message = ex.Message };
                }
            }
            //扣除积分
            var ch = CalculateIntegral(openId);
            if (ch)
            {
                return new Messages { IsSuc = true, Code = 1, Message = index.ToString() };
            }
            return new Messages { IsSuc = false, Code = -1, Message = "数据异常" };
        }

        #region 创建优惠券

        string SaveErpLog(string openId,int type,int index)
        {
            using (var dc = new HKEntities())
            {
                var date = DateTime.Now;
                string BillNo = "THQPr" + date.ToString("yyMMdd") + "KM01-001";
                var query = dc.KM_V_CardBinding.FirstOrDefault(t => t.OpenID == openId);
                string customerId = query.CustomerID;
                //优惠券有效期
                var startDate = DateTime.Now;
                var endDate = DateTime.Now;
                if (type == 1)
                {
                    startDate = Convert.ToDateTime("2018-04-27");
                    endDate = DateTime.Now.AddMonths(1).AddSeconds(-1);
                }
                if (type == 1 && index == 2)
                {
                    endDate = Convert.ToDateTime("2018-05-16 23:59:59");
                }
                if (type == 1 && index == 3)
                {
                    endDate = Convert.ToDateTime("2018-05-25 23:59:59");
                }
                if (type == 2)
                {
                    startDate = Convert.ToDateTime("2018-05-02"); ;
                    endDate = DateTime.Now.AddMonths(1).AddSeconds(-1);
                }
                if (type == 2 && index == 3)
                {
                    endDate = Convert.ToDateTime("2018-08-25 23:59:59");
                }
                if (type == 2 && index == 4)
                {
                    endDate = Convert.ToDateTime("2018-08-30 23:59:59");
                }
                //券类型
                var THQID =GetCardType(type, index);
                decimal amount = 10;
                if (type == 1 && index == 2)
                {
                    amount = 50;
                }
                else if (type == 1 && index == 3)
                {
                    amount = 3000;
                }
                else if (type == 2 && index == 2)
                {
                    amount = 20;
                }
                else if (type == 2 && index == 3)
                {
                    amount = 199;
                }
                else if (type == 2 && index == 4)
                {
                    amount = 10000;
                }
                //券号
                var THQNo = GetTHQNo();
                var addThqDetail = new Crm_Bas_THQDetail
                {
                    CompanyID = "KM",
                    BillNo = BillNo,
                    CustomerID = customerId,
                    THQID = THQID,
                    UseStartDate = startDate,
                    UseEndDate = endDate,
                    MiniAmounts = amount,
                    Amount = amount,
                    THQNo = THQNo,
                    THQStatus = "1",
                    PromoteTypeID = "0",
                    WXPublicNo = "",
                    WXOpenID = openId,
                    PromoteDate = DateTime.Now,
                    PromoteState = "0",
                    ModifyDTM = DateTime.Now,
                    Sequence = "",
                    BillTypeID = "Crm_CardRegDef",
                    THQRuleType = "1",
                    OldCustomerID = null,
                    StatusRemark = null,
                    PromoteUserID = null,
                    ISWX_HK = null
                    //SaleShopID = null
                };
                dc.Crm_Bas_THQDetail.Add(addThqDetail);
                try
                {
                    dc.SaveChanges();
                }
                catch (Exception ex)
                {
                   Log.Error(ex);
                }

                return THQNo;
            }
        }


        string GetCardType(int type,int index)
        {
            string THQID = string.Empty;
            //5.1活动只生成10元优惠券
            if (type == 1)
            {
                if(index==1)
                THQID = "KM000092";
                //if (index == 2)
                //    THQID = "KM000096";
                if (index == 2)
                    THQID = "KM000101";
                if (index == 3)
                    THQID = "KM000095";
            }
            else if (type == 2)
            {
                if (index == 1)
                    THQID = "KM000094";
                if (index == 2)
                    THQID = "KM000093";
                if (index == 3)
                    THQID = "KM000098";
                if (index == 4)
                    THQID = "KM000097";
            }
            return THQID;
        }
        

        /// <summary>
        /// 获取券号，14位，含数字字母随机生成，建议KM开头
        /// </summary>
        /// <returns>指定长度的随机字符串</returns>
        public string GetTHQNo()
        {
            string strSep = ",";
            char[] chrSep = strSep.ToCharArray();
            string strChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
            string[] aryChar = strChar.Split(chrSep, strChar.Length);
            string strRandom = string.Empty;

            var Rnd = new Random((int)DateTime.Now.Ticks);
            //生成随机字符串
            for (int i = 0; i < 12; i++)
            {
                strRandom += aryChar[Rnd.Next(aryChar.Length)];
            }
            return "KM" + strRandom;
        }

        #endregion

        #region 扣减积分
        /// <summary>
        /// 会员兑换积分实时更新到账户
        /// </summary>
        /// <param name="openId">会员ID</param>
        public bool CalculateIntegral(string openId)
        {
            //if (isDebug.ToLower() == "true") return false;
            using (var dc = new HKEntities())
            {
                var integral = 100;
                var vip = dc.KM_V_CardBinding.FirstOrDefault(t => t.OpenID == openId);
                if (vip != null)
                {
                    var userInfo = dc.CRM_Bas_CardInfo.FirstOrDefault(t => t.CardID == vip.CardID);
                    if (userInfo != null)
                    {
                        
                        userInfo.RemainIntegral -= integral;
                        userInfo.TotalIntegral -= integral;
                    }
                    var billNo = "KM" + vip.CardID + DateTime.Now.Ticks;
                    var master = new CRM_Oper_AdjIntegralMaster
                    {
                        AdjIntegralType = "999",
                        CompanyID = "KM",
                        BillDate = DateTime.Now,
                        BillNo = billNo,
                        ShopID = "",
                        BillStatus = 4,
                        Finished = false,
                        ModifyDTM = DateTime.Now,
                        Remark = "2018积分抽奖",
                        BillTypeID = "Crm_Oper_AdjInt",
                        IsPosBuild = false,
                        Checker = "KM00000005",
                        Operator = "KM00000005"
                    };
                    dc.CRM_Oper_AdjIntegralMaster.Add(master);
                    var seq = DateTime.Now.Ticks.ToString();
                    var detail = new CRM_Oper_AdjIntegralDetail
                    {
                        BillNo = master.BillNo,
                        CompanyID = master.CompanyID,
                        Sequence = seq,
                        CardTypeID = "00000000000036",
                        CardCode = vip.CardCode,
                        AdjustIntegral = integral,
                        NewIntegral = integral,
                        Remark = "2018积分抽奖",
                        ClearIntegralFlag = false,

                    };
                    dc.CRM_Oper_AdjIntegralDetail.Add(detail);
                    try
                    {
                        dc.SaveChanges();
                        Log.WriteLog("2018积分抽奖:用户编号 " + vip.CardID + ",扣除" + integral + "积分");
                        return true;
                    }
                    catch (Exception ex)
                    {
                        Log.WriteLog("用户编号 " + vip.CardID + " 扣除积分出错:" + ex);
                        return false;
                    }
                }

                return false;
            }
        }
        #endregion

        /// <summary>
        /// 限制奖品数量
        /// </summary>
        /// <param name="type"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        bool CheckLotteryCount(int type, int index)
        {
            var dc=new ActivityEntities();
            var count= dc.t_Lottery2018Activity_log.Count(t => t.ActivityType == type && t.LotteryType == index);
            if (type == 1)
            {
                return  count == 1;
            }

            if (type == 2)
            {
                switch (index)
                {
                    case 3:
                        return count >= 37;
                    case 4:
                        return count == 1;
                }
            }
            return false;
        }

        /// <summary>
        /// 生成奖项
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Dictionary<string, double> LoggeryInfo(int type)
        {
            var map=new Dictionary<string, double>();
            if (type == 1)
            {
                map.Add("未中奖", 0.79499);
                map.Add("10元优惠券", 0.2);
                map.Add("斜挎包", 0.005);
                map.Add("IPad", 0.00001);
            }
            if (type == 2)
            {
                map.Add("未中奖", 0.69985);
                map.Add("10元优惠券", 0.2);
                map.Add("20元优惠券", 0.1);
                map.Add("活力果汁机", 0.0001);
                map.Add("iPhoneX", 0.00005);
            }
            return map;
        }

        /// <summary>
        /// 中奖列表
        /// </summary>
        /// <param name="openId"></param>
        /// <param name="activityType">活动类型</param>
        /// <returns></returns>
        public List<LotteryResult> List(string openId,int activityType)
        {
            var dc = new ActivityEntities();
            var result = dc.t_Lottery2018Activity_log
                .Where(t => t.OpenID == openId && t.ActivityType == activityType && t.LotteryType>0)
                .Select(o => new LotteryResult
                {
                    ProductType  = o.LotteryType,
                    CreateDate = o.LotteryTime
                }).OrderByDescending(t=>t.CreateDate).ToList();
            return result;
        }

        /// <summary>
        /// 检查用户是否会员，成功返回用户积分
        /// </summary>
        /// <param name="openId"></param>
        /// <param name="type">type=1:首次进入；type=2:返回积分</param>
        /// <returns></returns>
        public LotteryUserInfo GetUser(string openId)
        {
            var dc = new HKERPEntities();
            var result = (from c in dc.KM_V_CardBinding
                          join m in dc.CRM_Bas_CardInfo on c.CardID equals m.CardID
                          where c.OpenID == openId
                          select new
                          {
                              c.OpenID,
                              c.CardID,
                              m.RemainIntegral
                          }).ToList().Select(o => new LotteryUserInfo()
                          {
                              OpenID = o.OpenID,
                              CardID = o.CardID,
                              TotalIntegral = o.RemainIntegral
                          }).FirstOrDefault();
            return result;
        }

        /// <summary>
        /// 中奖结果
        /// </summary>
        public List<Result2018Data> GetResult(int type)
        {
            var dc = new ActivityEntities();
            var query = (from r in dc.vm_Lottery2018Activity_log
                where r.ActivityType == type
                select new
                {
                    r,
                    list = (from l in dc.t_Lottery2018Activity_log
                        where l.ActivityType == type
                        group l by l.LotteryType
                        into g
                        select new
                        {
                            LotteryType = g.Key,
                            LotteryTypeCount = g.Count()
                        })
                }).ToList().OrderByDescending(t => t.r.Integral).Take(50).Select(o => new Result2018Data()
            {
                CustomerName = o.r.CustomerName,
                Tel = o.r.MobileTel,
                CardID = o.r.CardCode,
                TotalIntegral = o.r.Integral,
                list = o.list.ToList().Select(g => new Result2018Data.LotteryDetail()
                {
                    LotteryType = g.LotteryType,
                    Num = g.LotteryTypeCount
                })
            }).ToList();
            return query;
        }

        public Result2018Data.PrizeModel WelfareSummary(int ActivityType)
        {
            var hk = new HKEntities();
            var ae = new ActivityEntities();
            hk.Database.CommandTimeout = 0;
            var query = ae.t_Lottery2018Activity_log.Where(d => d.ActivityType == ActivityType);
            var applePrize = new Result2018Data.AppleModel();
            var blenderList = new List<Result2018Data.BlenderModel>();
            if (ActivityType == 1)
            {
                var apple = query.FirstOrDefault(d => d.LotteryType == 3);
                if (apple != null)
                {
                    var appleCustomer = (from a in hk.KM_V_CardBinding
                        join b in hk.CRM_Bas_CardInfo
                        on a.CardID equals b.CardID
                        where a.OpenID == apple.OpenID
                        select a).FirstOrDefault();
                    applePrize.CardCode = appleCustomer.CardCode;
                    applePrize.CustomerName = appleCustomer.CustomerName;
                    applePrize.LotteryTime = apple.LotteryTime.ToString("yyyy-MM-dd");
                    applePrize.Mobile = appleCustomer.MobileTel;
                }
            }
            else
            {
                var apple = query.FirstOrDefault(d => d.LotteryType == 4);
                if (apple != null)
                {
                    var appleCustomer = (from a in hk.KM_V_CardBinding
                        join b in hk.CRM_Bas_CardInfo
                        on a.CardID equals b.CardID
                        where a.OpenID == apple.OpenID
                        select a).FirstOrDefault();
                    applePrize.CardCode = appleCustomer.CardCode;
                    applePrize.CustomerName = appleCustomer.CustomerName;
                    applePrize.LotteryTime = apple.LotteryTime.ToString("yyyy-MM-dd");
                    applePrize.Mobile = appleCustomer.MobileTel;
                }
                var blender = query.Where(d => d.LotteryType == 3).GroupBy(d => d.OpenID).ToList();
                if (blender.Any())
                {
                    var blenderOpenIDs = blender.Select(d => d.Key).ToList();
                    var blenderCustomers = (from a in hk.KM_V_CardBinding
                        join b in hk.CRM_Bas_CardInfo
                        on a.CardID equals b.CardID
                        join c in blenderOpenIDs
                        on a.OpenID equals c
                        select a).ToList();
                    foreach (var item in blender)
                    {
                        var bc = blenderCustomers.FirstOrDefault(d => d.OpenID == item.Key);
                        var b = new Result2018Data.BlenderModel
                        {
                            CardCode = bc?.CardCode,
                            CustomerName = bc?.CustomerName,
                            LotteryTime = item.First().LotteryTime.ToString("yyyy-MM-dd"),
                            Mobile = bc?.MobileTel,
                            Count = item.Count()
                        };
                        blenderList.Add(b);
                    }
                }
            }
            var prizeTotalList = new List<Result2018Data.PrizeTotalModel>();
            var prize = query.GroupBy(d => d.LotteryType).OrderByDescending(d => d.Key);
            foreach (var item in prize)
            {
                var p = new Result2018Data.PrizeTotalModel();
                switch (item.Key)
                {
                    case 1:
                        p.PrizeName = "10元券";
                        p.PrizeCount = item.Count();
                        prizeTotalList.Add(p);
                        break;
                    case 2:
                        p.PrizeName = ActivityType == 1 ? "斜挎包" : "20元券";
                        p.PrizeCount = item.Count();
                        prizeTotalList.Add(p);
                        break;
                    case 3:
                        p.PrizeName = ActivityType == 1 ? "iPad" : "果汁机";
                        p.PrizeCount = item.Count();
                        prizeTotalList.Add(p);
                        break;
                    case 4:
                        p.PrizeName = ActivityType == 1 ? "" : "iPhone X";
                        p.PrizeCount = item.Count();
                        prizeTotalList.Add(p);
                        break;
                    default: break;
                }
            }
            var totalP = new Result2018Data.PrizeTotalModel
            {
                PrizeName = "抽奖总积分",
                PrizeCount = query.Count() * 100
            };
            prizeTotalList.Add(totalP);
            var totalCustomer = new Result2018Data.PrizeTotalModel
            {
                PrizeName = "抽奖总人数",
                PrizeCount = query.GroupBy(d => d.OpenID).Count()
            };
            prizeTotalList.Add(totalCustomer);
            var lotteryList = new List<Result2018Data.LotteryModel>();
            var lottery = query.Where(d => d.LotteryType != 3 && d.LotteryType != 4 && d.LotteryType != 0)
                .GroupBy(d => d.OpenID).OrderByDescending(d => d.Count()).Take(50);
            var lotteryOpenIDs = lottery.Select(d => d.Key).ToList();
            var lotteryCustomers = (from a in hk.KM_V_CardBinding
                join b in hk.CRM_Bas_CardInfo
                on a.CardID equals b.CardID
                join c in lotteryOpenIDs
                on a.OpenID equals c
                select a).ToList();
            foreach (var item in lottery)
            {
                var lc = lotteryCustomers.FirstOrDefault(d => d.OpenID == item.Key);
                var l = new Result2018Data.LotteryModel
                {
                    CardCode = lc?.CardCode,
                    CustomerName = lc?.CustomerName,
                    Integral = query.Count(d => d.OpenID == item.Key) * 100,
                };
                var p1 = item.Where(d => d.LotteryType == 1);
                var p2 = item.Where(d => d.LotteryType == 2);
                if (ActivityType == 1)
                {
                    l.PrizeName = string.Format("{0}",
                        p1.Any() ? string.Format("10元优惠券{0}", p2.Any() ? "(背包)" : "") : p2.Any() ? "背包" : "");
                    l.PrizeCount = string.Format("{0}",
                        p1.Any()
                            ? string.Format("{0}{1}", p1.Count(), p2.Any() ? string.Format("({0})", p2.Count()) : "")
                            : p2.Any()
                                ? p2.Count().ToString()
                                : "");
                }
                else
                {
                    l.PrizeName = "10/20元优惠券";
                    l.PrizeCount = (p1.Count() + p2.Count()).ToString();
                }
                lotteryList.Add(l);
            }
            var result = new Result2018Data.PrizeModel
            {
                PrizeTotalList = prizeTotalList,
                ApplePrize = applePrize,
                BlenderList = blenderList,
                LotteryList = lotteryList,
            };
            return result;
        }

    }

    /// <summary>
    /// 用户相关信息
    /// </summary>
    [Serializable]
    public class LotteryUserInfo
    {
        public string OpenID { get; set; }

        public string CardID { get; set; }

        public decimal? TotalIntegral { get; set; }

        public IList<int> Indexs { get; set; }
    }

    public class Result2018Data: LotteryUserInfo
    {
        public  string Tel { get; set; }

        public string CustomerName { get; set; }

        public IEnumerable<LotteryDetail> list { get; set; }

        public class LotteryDetail
        {
            /// <summary>
            /// 中奖类型
            /// </summary>
            public  int LotteryType { get; set; }
            
           /// <summary>
           ///  数量
           /// </summary>
           public  int Num { get; set; }
        }

        public class PrizeModel
        {
            public IList<PrizeTotalModel> PrizeTotalList { get; set; }
            public AppleModel ApplePrize { get; set; }
            public IList<BlenderModel> BlenderList { get; set; }
            public IList<LotteryModel> LotteryList { get; set; }
        }

        public class PrizeTotalModel
        {
            public string PrizeName { get; set; }
            public int PrizeCount { get; set; }
        }

        public class CustomerModel
        {
            public string CustomerName { get; set; }
            public string CardCode { get; set; }
        }

        public class AppleModel:CustomerModel
        {
            public string Mobile { get; set; }
            public string LotteryTime { get; set; }
        }

        public class BlenderModel:CustomerModel
        {
            public string Mobile { get; set; }
            public int Count { get; set; }
            public string LotteryTime { get; set; }
        }

        public class LotteryModel: CustomerModel
        {
            public string PrizeName { get; set; }
            public string PrizeCount { get; set; }
            public int Integral { get; set; }
        }

    }
}
